from typing import Dict, Any, List
from protocol.codec import write_uint
from datetime import datetime, timezone, timedelta




def encode_time_bcd(field_cfg: Dict[str, Any]) -> bytes:
    digits = int(field_cfg.get('digits', 12))
    if digits % 2 != 0:
        raise ValueError('BCD digits 必须为偶数')
    mode = field_cfg.get('mode', 'system_beijing')
    if mode == 'direct':
        val = str(field_cfg['value'])
        if len(val) != digits or not val.isdigit():
            raise ValueError(f'time 直接值必须为{digits}位数字')
        out = bytearray()
        for i in range(0, digits, 2):
            high = int(val[i])
            low = int(val[i + 1])
            out.append(((high & 0x0F) << 4) | (low & 0x0F))
        return bytes(out)
    # system_beijing 仅支持12位YYMMDDhhmmss
    if digits != 12:
        raise ValueError('system_beijing 模式仅支持 digits=12')
    tz = timezone(timedelta(hours=8))
    now = datetime.now(tz)
    parts = [now.year % 100, now.month, now.day, now.hour, now.minute, now.second]
    out = bytearray()
    for p in parts:
        out.append(((p // 10) << 4) | (p % 10))
    return bytes(out)






def pad_bytes_ff(data: bytes, total_len: int) -> bytes:
    if len(data) > total_len:
        raise ValueError('超出最大字节长度')
    return data + bytes([0xFF]) * (total_len - len(data))


def write_len_by_prefix(prefix: str, n: int) -> bytes:
    p = prefix.upper()
    if p == 'BYTE':
        if n < 0 or n > 0xFF:
            raise ValueError(f'长度超界(BYTE): {n}')
        return write_uint(n, 1)
    if p == 'WORD':
        if n < 0 or n > 0xFFFF:
            raise ValueError(f'长度超界(WORD): {n}')
        return write_uint(n, 2)
    if p == 'DWORD':
        if n < 0 or n > 0xFFFFFFFF:
            raise ValueError(f'长度超界(DWORD): {n}')
        return write_uint(n, 4)
    raise ValueError(f'未知长度前缀: {prefix}')

